/**
 *  ItemStack.java : IceBird project
 *  16:23:19 
 */
package icebird.compiler.x86.old;

/**
 * @author Sergey Shulepoff[Knott]
 */
public class ItemStack {
	
	protected Item[] stack;
	protected int peek;
	
	private final int maxSize;
	
	public ItemStack(int max) {
		maxSize = max;
		
		reset();
	}
	
	/**
	 * Reset stack.
	 * @return void
	 */
	public void reset() {
		stack = new Item[Math.min(8, maxSize)];
		peek = 0;
	}
	
	/**
	 * Grow stack space.
	 * @return void
	 */
	private final void grow() {
		if (stack.length == maxSize) {
			throw new StackOverflowError();
		} else {
			Item[] tmp = new Item[Math.min(maxSize, stack.length * 2)];
			System.arraycopy(stack, 0, tmp, 0, stack.length);
			stack = tmp;
		}
	}
	
	/**
	 * Get peek of stack.
	 * @return Item
	 */
	public Item getPeek() {
		return stack[peek - 1];
	}
	
	/**
	 * Has capcity?
	 * @return boolean
	 */
	public final boolean hasCapacity(int items) {
		return (maxSize + items <= maxSize);
	}
	
	/**
	 * Pop
	 * @return void
	 */
	public void pop() {
		if (peek <= 0) {
			throw new StackOverflowError();
		}
		
		peek--;
	}
	
	/**
	 * Pop
	 * @return void
	 */
	public void pop(Item i) {
		pop();
		Item p = getPeek();
		
		if (p != i) {
			throw new StackOverflowError();
		}
	}
	
	public void push(Item i) {
		if (peek == stack.length) {
			grow();
		}
		stack[peek++] = i;
	}
	
    final void visitItems(ItemVisitor visitor) {
        for (int i = 0; i < peek; i++) {
            visitor.visit(stack[i]);
        }
    }
}
